﻿using System;
using System.Windows;
using GalaSoft.MvvmLight.Messaging;
using WpWinNl.Behaviors;
#if WINDOWS_PHONE
using System.Windows.Controls;
#else
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml;
#endif

namespace WpWinNl.Audio
{
  public class PlaySoundEffectBehavior : SafeBehavior<MediaElement>
  {
    public PlaySoundEffectBehavior()
    {
#if WINDOWS_PHONE
      ListenToPageBackEvent = true;
#endif
      
    }
    protected override void OnSetup()
    {
      Messenger.Default.Register<PlaySoundEffectMessage>(this, DoPlaySoundFile);
      AssociatedObject.IsHitTestVisible = false;
      AssociatedObject.AutoPlay = false;
#if WINDOWS_PHONE
      var soundUri = new Uri(SoundFileLocation, UriKind.Relative);
#else
      var soundUri = new Uri(AssociatedObject.BaseUri, SoundFileLocation);
#endif

      AssociatedObject.Source = soundUri;
      AssociatedObject.Position = TimeSpan.FromSeconds(0);
      SetRepeat(Repeat);
    }

    private void DoPlaySoundFile(PlaySoundEffectMessage message)
    {
      AssociatedObject.Stop();

      if (SoundName == message.SoundName)
      {
        if (message.Start)
        {
          AssociatedObject.Position = TimeSpan.FromSeconds(0);
          AssociatedObject.Play();
        }
      }
    }

    private void SetRepeat(bool repeat)
    {
      if (AssociatedObject != null)
      {
        if (repeat)
        {
          AssociatedObject.MediaEnded += AssociatedObjectMediaEnded;
        }
        else
        {
          AssociatedObject.MediaEnded -= AssociatedObjectMediaEnded;
        }

      }
    }

    private void AssociatedObjectMediaEnded(object sender, RoutedEventArgs e)
    {
      AssociatedObject.Position = TimeSpan.FromSeconds(0);
      AssociatedObject.Play();
    }


    protected override void OnCleanup()
    {
      Messenger.Default.Unregister(this);
      AssociatedObject.MediaEnded -= AssociatedObjectMediaEnded;
    }

    #region SoundFileLocation

    public const string SoundFileLocationPropertyName = "SoundFileLocation";

    public string SoundFileLocation
    {
      get { return (string)GetValue(SoundFileLocationProperty); }
      set { SetValue(SoundFileLocationProperty, value); }
    }

    public static readonly DependencyProperty SoundFileLocationProperty = DependencyProperty.Register(
      SoundFileLocationPropertyName,
      typeof(string),
      typeof(PlaySoundEffectBehavior),
      new PropertyMetadata(String.Empty));

    #endregion

    #region SoundName

    /// <summary>
    /// SoundName Property name
    /// </summary>
    public const string SoundNamePropertyName = "SoundName";

    public string SoundName
    {
      get { return (string)GetValue(SoundNameProperty); }
      set { SetValue(SoundNameProperty, value); }
    }

    /// <summary>
    /// SoundName Property definition
    /// </summary>
    public static readonly DependencyProperty SoundNameProperty = DependencyProperty.Register(
        SoundNamePropertyName,
        typeof(string),
        typeof(PlaySoundEffectBehavior),
        new PropertyMetadata(default(string)));

    #endregion

    #region Repeat

    /// <summary>
    /// Repeat Property name
    /// </summary>
    public const string RepeatPropertyName = "Repeat";

    public bool Repeat
    {
      get { return (bool)GetValue(RepeatProperty); }
      set { SetValue(RepeatProperty, value); }
    }

    /// <summary>
    /// Repeat Property definition
    /// </summary>
    public static readonly DependencyProperty RepeatProperty = DependencyProperty.Register(
        RepeatPropertyName,
        typeof(bool),
        typeof(PlaySoundEffectBehavior),
        new PropertyMetadata(default(bool), RepeatChanged));

    /// <summary>
    /// Repeat property changed callback.
    /// </summary>
    /// <param name="d">The depency object (i.e. the behavior).</param>
    /// <param name="e">The property event args <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>  
    public static void RepeatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      var behavior = d as PlaySoundEffectBehavior;
      var newValue = (bool)e.NewValue;
      if (behavior != null)
      {
        behavior.SetRepeat(newValue);
      }
    }

    #endregion
  }
}
